package com.kotlinx.view.base

import android.app.Activity
import android.app.Dialog
import android.content.Context
import android.content.res.Resources
import android.graphics.Color
import android.graphics.drawable.GradientDrawable
import android.os.Bundle
import android.util.DisplayMetrics
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.Window
import android.view.WindowManager
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import com.kotlinx.view.R
import com.kotlinx.view.utils.ViewThread


/**
 * 自定义dialog快速创建基类
 * @author 余静 2022年3月14日22:59:49
</B> */
/*
用法：
//kotlin
class TestDialog(activity: Activity) : YBaseDialog<TestDialogBinding>(activity, R.layout.test_dialog) {
    init {
        fullscreen = true
        openAnimation = false
    }
    override fun init() {
    }
}
//java
public class TestDialog extends YBaseDialog<TestDialogBinding> {

    public TestDialog(@NotNull Activity activity, int layout) {
        super(activity, layout);
    }

    @Override
    protected void init() {

    }
}
//或者
YBaseDialog dialog = new YBaseDialog<DialogInfoBinding>(this, R.layout.dialog_info,
       android.R.style.Theme_DeviceDefault_Dialog_NoActionBar) {
    @Override
    protected void init() {

    }
};
dialog.show();
 */
abstract class YBaseDialog<B : ViewDataBinding> : Dialog {
    constructor(activity: Activity, layout: Int, style: Int = android.R.style.Theme_DeviceDefault_Dialog_NoActionBar) : super(activity, style) {
        this.activity = activity
        this.layout = layout
    }

    constructor(activity: Activity, view: View, style: Int = android.R.style.Theme_DeviceDefault_Dialog_NoActionBar) : super(activity, style) {
        this.activity = activity
        this.view = view
    }

    var activity: Activity
    var layout: Int? = null
    lateinit var view: View
    lateinit var binding: B
    var screenWidthDp: Float? = null //开发屏幕最小宽度
    var cancel: Boolean //能取消
    var alpha: Float //透明
    var dimAmount: Float //模糊
    var widthPixels: Float //宽
    var heightPixels: Float //高
    var fullscreen: Boolean //全屏显示
    var disableInput: Boolean //禁用输入法
    var openAnimation: Boolean //打开动画
    var strokeWidth: Float? // 边框宽度，乘以屏幕比例
    var roundRadius: Float? // 圆角半径，乘以屏幕比例
    var strokeColor: Int //边框颜色
    var fillColor: Int  //填充颜色
    var dismissListener: (() -> Unit)? = null //关闭前回调

    //根据屏幕赋默认值
    init {
        val width = Resources.getSystem().displayMetrics.widthPixels
        val height = Resources.getSystem().displayMetrics.heightPixels
        //如果是竖屏
        if (height > width) {
            widthPixels = 0.8F //宽
            heightPixels = 0.32F //高
            fullscreen = false //全屏
        } else {
            widthPixels = 0.5f //宽
            heightPixels = 0.5f //高
            fullscreen = true //全屏
        }
        cancel = true //能取消
        alpha = 1f //透明
        dimAmount = 0.4f //模糊
        disableInput = false //禁用输入法
        openAnimation = true //打开动画
        strokeWidth = null // 边框宽度，乘以屏幕比例
        roundRadius = null // 圆角半径，乘以屏幕比例
        strokeColor = Color.parseColor("#FFFFFFFF") //边框颜色
        fillColor = Color.parseColor("#FFFFFFFF") //填充颜色
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initBefore()
        //720F
        if (screenWidthDp == null) {
            val sWidth = activity.resources.configuration.smallestScreenWidthDp //屏幕最小宽度
            screenWidthDp = sWidth.toFloat()
        }
        if (layout != null)
            view = LayoutInflater.from(activity).inflate(layout!!, null)

        setContentView(view) // 设置布局view
        binding = DataBindingUtil.bind(view)!!

        //当前屏幕与开发屏幕的比例
        val scaleScreenWidthDp = activity.resources.configuration.smallestScreenWidthDp / (if (screenWidthDp == null) 720F else screenWidthDp!!)
        if (strokeWidth == null) strokeWidth = 2 * scaleScreenWidthDp // 2dp 边框宽度，乘以屏幕比例
        if (roundRadius == null) roundRadius = 16 * scaleScreenWidthDp // 16dp 圆角半径，乘以屏幕比例

        val window = window
        window?.let { initWindow(it) }
        if (openAnimation) window?.setWindowAnimations(R.style.yDialogWindowAnimation) //动画

        super.setCancelable(cancel) // 是否允许按返回键
        setCanceledOnTouchOutside(cancel) // 触摸屏幕其他区域不关闭对话框

        init()
        initAfter()
    }

    /**
     * 初始化数据
     */
    protected abstract fun init()
    open fun initBefore() {}
    open fun initAfter() {}

    /**
     * 是否能取消
     */
//    open fun isCancelable(): Boolean {
//        return mCancelable
//    }

    /* *************************基本设置************************** */ //配置dialog基本属性
    private fun initWindow(window: Window) {
        if (disableInput) {
            //启动不弹出输入法
            window.setFlags(
                WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
                WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
            )
        }
        // 设置Gravity居中
        window.setGravity(Gravity.CENTER)
        //获取LayoutParams对象
        val lp = window.attributes
        //设置透明度
        lp.alpha = alpha
        //设置模糊度
        lp.dimAmount = dimAmount
        //设置宽高
        val dm = activity.resources.displayMetrics
        if (widthPixels > 0)
            lp.width = (dm.widthPixels * widthPixels).toInt()
        if (heightPixels > 0)
            lp.height = (dm.heightPixels * heightPixels).toInt()
        //应用设置
        window.attributes = lp
        //设置window的Background为圆角
        val gradientDrawable = GradientDrawable()
        gradientDrawable.setColor(fillColor)
        gradientDrawable.cornerRadius = dp2px(roundRadius!!).toFloat()
        gradientDrawable.setStroke(dp2px(strokeWidth!!), strokeColor)
        //应用背景颜色
        window.setBackgroundDrawable(gradientDrawable)
    }

    override fun show() {
        if (activity.isFinishing) return
        if (ViewThread.isMainThread()) {
            //主要作用是焦点失能和焦点恢复，保证在弹出dialog时不会弹出虚拟按键且事件不会穿透。
            if (fullscreen && this.window != null) {
                this.window!!.setFlags(
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                )
                this.window!!.decorView.systemUiVisibility =
                    View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                super.show()
                this.window!!.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
            } else {
                super.show()
            }
        } else {
            ViewThread.runOnUiThread { this.show() }
        }
    }

    fun show(time: Int) {
        show()
        ViewThread.runOnUiThreadDelayed({ dismiss() }, time.toLong())
    }

    fun show(time: Int, dismissListener: (() -> Unit)? = null) {
        show()
        ViewThread.runOnUiThreadDelayed({
            dismissListener?.invoke()
            dismiss()
        }, time.toLong())
    }

    override fun dismiss() {
        dismissListener?.invoke()
        super.dismiss()
    }

    /**
     * dip转px
     *
     * @param dpValue 传入dip
     * @return 转换后的px
     */
    open fun dp2px(dpValue: Float): Int {
        val scale = Resources.getSystem().displayMetrics.density
        return (dpValue * scale + 0.5f).toInt()
    }

    /**
     * px转dip
     *
     * @param pxValue px
     * @return dp
     */
    open fun px2dp(pxValue: Int): Float {
        val scale = Resources.getSystem().displayMetrics.density
        return pxValue / scale + 0.5f
    }

    /**
     * sp转换为px
     * @param spValue sp值
     * @return 转换后的px值
     */
    open fun sp2px(spValue: Float): Int {
        return (spValue * Resources.getSystem().displayMetrics.scaledDensity + 0.5f).toInt()
    }

    /**
     * px转换为sp
     * @param pxValue px值
     * @return 转换后的sp值
     */
    open fun px2sp(pxValue: Int): Float {
        return pxValue / Resources.getSystem().displayMetrics.scaledDensity + 0.5f
    }


    /**
     * 获取屏幕宽度
     */
    open fun getScreenWidth(): Int {
        return Resources.getSystem().displayMetrics.widthPixels //getDisplayMetrics(activity).widthPixels
    }

    /**
     * 获取屏幕高度
     */
    open fun getScreenHeight(): Int {
        return Resources.getSystem().displayMetrics.heightPixels //getDisplayMetrics(activity).heightPixels
    }

    open fun getDisplayMetrics(context: Context): DisplayMetrics {
        val manager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        val metrics = DisplayMetrics()
        manager.defaultDisplay?.getRealMetrics(metrics)
        return metrics
    }
}